How to show values from a field in the input tag or textarea tag in modal widget

nwang
Mega Contributor

Hi guys,

 

I'm still not familiar with angular. I'm not sure how to get the values from a field and show it into the input so that users can modify and update them.

 

 I tried with ng-init so that the ng-model can pass the data to the server.

 

HTML Code:

 

<span class="fa fa-asterisk mandatory"></span>
Short Description<br>

<input type="text" id="short_description" name="short_description" class="form-control" ng-model="c.data.short_description" ng-init="c.data.short_description={{short_description}}" required/><br>

 

<span class="fa fa-asterisk mandatory"></span>
Justification<br>

<textarea rows="4" cols="50" style="resize: none;" class="form-control" ng-model="c.data.justification" required>${data.justification}</textarea><br>

 

1 ACCEPTED SOLUTION

ChrisBurks
Mega Sage

Hello nwang,


To start off ng-init and ng-model is not really used to pass data to the server.

- ngInit allows you to evaluate expressions ie: c.data.short_description = 'Hello World'
- ngModel can be used on inputs, textareas, and select elements. It binds them to a property on the scope.
Official docs for ngModel: https://docs.angularjs.org/api/ng/directive/ngModel

ngInit is not necessary here because ngModel can be initalized by the c.data.short_description value, if any.
The data object is server side so initially the value is coming from the server first.

<input name="short_description" ng-model="c.data.short_description" ng-require="true">

With that, if c.data.short_description has a value from the server then it should display in the input field.

It's the same for the textarea. Although, by your markup I believe you're expecting it to be blank. I would use a placeholder.

<textarea rows="4" cols="50" style="resize: none;" class="form-control" ng-model="c.data.justification" ng-require="true" placeholder="${Justification}"></textarea>

At a basic level nothing needs to be done to capture the values of the two form inputs at this point.
This is because of two things.
1) ngModel for the respective inputs have been set to be populated with values. Those values can be obtained from c.data.<respective property name> in the Client controller
2) ServiceNow has graciously provided an input object to use to help pass data from inputs back to the server using the "name" attributes from the form input elements "input" and "textarea".
This is done with c.server.update($scope)

Now you just need a mechanism like a submit button or a watcher to let the system know when to send new data.

Here's a loose example based on your post. I'm going to use a dummy incident.

HTML Markup:

<div>
  <form>
    <input name="myInputModel" class="form-control" ng-model="c.data.myInputModel" ng-required="true">
    
    <textarea 
              name="myTextareaModel" 
              class="form-control m-t" 
              ng-required="true" 
              ng-model="c.data.myTextareaModel" 
              placeholder="${Add a description}"
              ></textarea>

    <div class="m-t-lg">
      <button class="btn btn-primary pull-right" ng-click="passData()">${Submit}</button>
    </div>
  </form>
</div>

 

Server Script:

(function() {
  /* populate the 'data' object */
  /* e.g., data.table = $sp.getValue('table'); */
	
	//Static incident sys_id for demo:
	var sys_id = 'a1a0199bdb761700860bd421cf9619c3';

	// Gets values if no input is given
	if(!input){
		var inc = new GlideRecord('incident');
		inc.get(sys_id);
		if(inc.getUniqueValue()) {
			data.myInputModel = inc.getValue('short_description');
			data.myTextareaModel = inc.getValue('description');
		}
		return;
	}
	
	// If input is submitted then grab any input values from input fields 
        // based on their names (name attribute on element)
        // and update this case a record
	if(input){
		var inc = new GlideRecord('incident');
		inc.get(sys_id);
		inc.setValue('short_description', input.myInputModel);
		inc.setValue('description', input.myTextareaModel);
		inc.update();
	}
})();

Client controller:

function($scope) {
  
  var c = this;

  // update the server
  $scope.passData = function(){
     c.server.update();
  }
}

 

Short screencast of the code in action:

View solution in original post

5 REPLIES 5

ChrisBurks
Mega Sage

Hello nwang,


To start off ng-init and ng-model is not really used to pass data to the server.

- ngInit allows you to evaluate expressions ie: c.data.short_description = 'Hello World'
- ngModel can be used on inputs, textareas, and select elements. It binds them to a property on the scope.
Official docs for ngModel: https://docs.angularjs.org/api/ng/directive/ngModel

ngInit is not necessary here because ngModel can be initalized by the c.data.short_description value, if any.
The data object is server side so initially the value is coming from the server first.

<input name="short_description" ng-model="c.data.short_description" ng-require="true">

With that, if c.data.short_description has a value from the server then it should display in the input field.

It's the same for the textarea. Although, by your markup I believe you're expecting it to be blank. I would use a placeholder.

<textarea rows="4" cols="50" style="resize: none;" class="form-control" ng-model="c.data.justification" ng-require="true" placeholder="${Justification}"></textarea>

At a basic level nothing needs to be done to capture the values of the two form inputs at this point.
This is because of two things.
1) ngModel for the respective inputs have been set to be populated with values. Those values can be obtained from c.data.<respective property name> in the Client controller
2) ServiceNow has graciously provided an input object to use to help pass data from inputs back to the server using the "name" attributes from the form input elements "input" and "textarea".
This is done with c.server.update($scope)

Now you just need a mechanism like a submit button or a watcher to let the system know when to send new data.

Here's a loose example based on your post. I'm going to use a dummy incident.

HTML Markup:

<div>
  <form>
    <input name="myInputModel" class="form-control" ng-model="c.data.myInputModel" ng-required="true">
    
    <textarea 
              name="myTextareaModel" 
              class="form-control m-t" 
              ng-required="true" 
              ng-model="c.data.myTextareaModel" 
              placeholder="${Add a description}"
              ></textarea>

    <div class="m-t-lg">
      <button class="btn btn-primary pull-right" ng-click="passData()">${Submit}</button>
    </div>
  </form>
</div>

 

Server Script:

(function() {
  /* populate the 'data' object */
  /* e.g., data.table = $sp.getValue('table'); */
	
	//Static incident sys_id for demo:
	var sys_id = 'a1a0199bdb761700860bd421cf9619c3';

	// Gets values if no input is given
	if(!input){
		var inc = new GlideRecord('incident');
		inc.get(sys_id);
		if(inc.getUniqueValue()) {
			data.myInputModel = inc.getValue('short_description');
			data.myTextareaModel = inc.getValue('description');
		}
		return;
	}
	
	// If input is submitted then grab any input values from input fields 
        // based on their names (name attribute on element)
        // and update this case a record
	if(input){
		var inc = new GlideRecord('incident');
		inc.get(sys_id);
		inc.setValue('short_description', input.myInputModel);
		inc.setValue('description', input.myTextareaModel);
		inc.update();
	}
})();

Client controller:

function($scope) {
  
  var c = this;

  // update the server
  $scope.passData = function(){
     c.server.update();
  }
}

 

Short screencast of the code in action:

nwang
Mega Contributor

Thank you sooo muchh!!!!! YES, this solves the issue. Thank you for the information.

 

Before I checked your reply, I actually found a way to get the values with the html code that I have posted before. The problem with this is that I have a sn-record-picker tag and is refreshing the values of the input and textarea. I have no idea why it is doing that. 

This is my code:

(function(){
var gr = $sp.getRecord();
var table = gr.getTableName();
data.canRead = gr.canRead();

if (!data.canRead)
return;
data.short_description = gr.getValue('short_description');
data.justification = gr.getValue('justification');

data.tableLabel = gr.getLabel();

data.table = table;
data.sys_id = gr.getUniqueValue();
})();

 

I replaced it with your code that fixed my issue:

if(!input){
var inc = new GlideRecord('incident');
inc.get(sys_id);
if(inc.getUniqueValue()) {
data.myInputModel = inc.getValue('short_description');
data.myTextareaModel = inc.getValue('justification');
}
return;
}

 

Thanks!!!

Hi Chris,

Thank you for composing a comprehensive answer which addresses the question cleanly.

regards .. John

vinithec22
Tera Contributor

Can anyone help me learn these things provide me documentation link it will be helpful